package algebra.visitors.cursors;

import algebra.op.AlgebraicOP;
import algebra.op.ScanOP;
//import algebra.query.OrderingDescription;
import algebra.query.indexing.DescriptionIndex;
import entities.assertion.ConceptAssertion;

public class CACursorScan extends CACursor {
	private final ScanOP op;
	private CACursor subcursor;
	private final DescriptionIndex di;
	private ConceptAssertion subCA;
	private CACursorDI dic;
//	private boolean star;
//	private int checkpoint;
	private boolean sortResults;

	public CACursorScan(ScanOP op) {
		this.op = op;
		subcursor = null;
		this.di = op.getSecondaryIndex().getDescriptionIndex();
		this.sortResults = false;
	}
	
	public CACursorScan(ScanOP op, boolean sort) {
		this(op);
		this.sortResults = sort;
	}
	

	@Override
	public boolean openCursor() {
		AlgebraicOP subop = this.op.getSubquery();
		this.subcursor = CACursor.getNewCACursor(subop);
		this.subcursor.openCursor();
		subCA = this.subcursor.getNextResult();
		dic = new CACursorDI(di, subCA, di.getRoot(), this.sortResults, op.getSecondaryIndex().getCi());
		dic.openCursor();
		return true;
	}



//	private ConceptAssertion getNextResultWithoutSearch() {
//
//		// use an index/table scan only
//		List<ConceptAssertion> indexCAs = new ArrayList<ConceptAssertion>();
//		indexCAs.addAll(this.di.viewAsConceptAssertions());
//		while (this.checkpoint >= 0 && this.checkpoint < indexCAs.size()) {
//			ConceptAssertion ic = indexCAs.get(checkpoint++);
//			// optimization
//			if (star && notestRequired) {
//				return ic;
//			}
//			//
//			ConceptAssertion test = new ConceptAssertion(ic.getIndividual(),
//					subCA.getConcept());
//			try {
//				if (new KBReason(false).logicConsequence(ic, test, null)) {
//					return ic;
//				}
//			} catch (CoreReasoningException e) {
//				e.printStackTrace();
//			}
//		}
//		return null;
//	}

	@Override
	public ConceptAssertion getNextResult() {
		if (di == null || subCA == null) {
			// this index is not materialized yet.
			return null;
		}
		ConceptAssertion ret = dic.getNextResult();
		if (ret == null) {
			subCA = this.subcursor.getNextResult();
			if (subCA == null) {
				return null;
			} else {
				dic = new CACursorDI(di, subCA, di.getRoot(), this.sortResults, op.getSecondaryIndex().getCi());
				dic.openCursor();
				return getNextResult();
			}
		} else {
			return ret;
		}
	}

	@Override
	public boolean isSortedById() {
		//subquery must produce answers in order, and searching the tree in order as well
		return this.subcursor.isSortedById() && this.dic.isSortedById();
	}

}
